package com.qboot.core.aspect;

import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import com.alibaba.fastjson.JSON;
import com.qboot.common.annotation.LoginLog;
import com.qboot.common.properties.QbootProperties;
import com.qboot.common.utils.SpringUtils;
import com.qboot.system.entity.SysLoginLog;
import com.qboot.system.service.SysLoginLogService;
import com.qboot.system.vo.LoginBodyVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import java.lang.reflect.Method;
import java.util.Date;

/**
 * 登录日志切面
 *
 * @author Tellsea
 * @date 2022/12/15
 */
@Slf4j
@Aspect
@Component
@SuppressWarnings("all")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class LoginLogAspect {

    private final QbootProperties qbootProperties;
    private final SysLoginLogService sysLoginLogService;

    /**
     * 获取浏览器名字
     *
     * @return
     */
    public static String getBrowserName() {
        String uaStr = SpringUtils.getRequest().getHeader("User-Agent");
        UserAgent ua = UserAgentUtil.parse(uaStr);
        return ua.getBrowser().toString();
    }

    /**
     * 获取浏览器版本
     *
     * @return
     */
    public static String getBrowserVersion() {
        String uaStr = SpringUtils.getRequest().getHeader("User-Agent");
        UserAgent ua = UserAgentUtil.parse(uaStr);
        return ua.getVersion();
    }

    /**
     * 获取操作系统名称
     *
     * @return
     */
    public static String getOsName() {
        String uaStr = SpringUtils.getRequest().getHeader("User-Agent");
        UserAgent ua = UserAgentUtil.parse(uaStr);
        return ua.getOs().toString();
    }

    @Pointcut("@annotation(com.qboot.common.annotation.LoginLog)")
    public void logAspect() {
    }

    @Around("logAspect()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object result = null;
        MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
        Method method = signature.getMethod();
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        result = proceedingJoinPoint.proceed();
        stopWatch.stop();
        if (qbootProperties.getIsLoginLog()) {
            LoginLog loginLog = method.getAnnotation(LoginLog.class);
            LoginBodyVo loginBodyVo = JSON.parseObject(JSON.toJSONString(proceedingJoinPoint.getArgs()[0]), LoginBodyVo.class);
            SysLoginLog sysLoginLog = new SysLoginLog();
            sysLoginLog.setUserName(loginBodyVo.getUsername());
            sysLoginLog.setOperationIp(ServletUtil.getClientIP(SpringUtils.getRequest()));
            sysLoginLog.setUsageTime(stopWatch.getTotalTimeMillis());
            sysLoginLog.setOperationOs(getOsName());
            sysLoginLog.setBrowserType(getBrowserName());
            sysLoginLog.setBrowserVersion(getBrowserVersion());
            sysLoginLog.setResponseResult(JSON.toJSONString(result));
            sysLoginLog.setOperationTime(new Date());
            sysLoginLogService.save(sysLoginLog);
        }
        return result;
    }
}
